﻿using MediatR;
using Service.Auth.Api.Application.Command;
using Service.Auth.Api.Application.Notification;
using Service.Auth.Api.Application.Query;
using Service.Auth.Api.Application.Query;
using Service.Auth.Domain.AggregatesModel;
using Service.Auth.Domain.Events;
using Service.Auth.Model.Enum;
using Service.Auth.Model.Model.Dto;
using Service.Auth.Model.Model.RequestDto.UserSystem;
using Service.Core.Redis.Services;
using Service.Core.Repository;
using Service.Framework.Utils;

namespace Service.Auth.Api.Application.DomainEventHandlers;

/// <summary>
/// 
/// </summary>
/// <param name="roleRepository"></param>
/// <param name="userQueryService"></param>
/// <param name="redisService"></param>
/// <param name="logger"></param>
/// <param name="mediator"></param>
public class UserDomainEventHandler(IRepository<Role> roleRepository, UserQueryService userQueryService, IRedisService redisService,
    ILogger<UserAddSystemRolesDomainEvent> logger, IMediator mediator)
    :
        INotificationHandler<UserAddSystemRolesDomainEvent>,
    INotificationHandler<ChangeUserDomainEvent>,
        INotificationHandler<ChangePasswordDomainEvent>,
        INotificationHandler<UserChangeStatusDomainEvent>
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="notification"></param>
    /// <param name="cancellationToken"></param>
    public async Task Handle(UserAddSystemRolesDomainEvent notification, CancellationToken cancellationToken)
    {
        logger.LogInformation("Notification User Add UserSystemRoles....");
        var roles = await roleRepository.GetListAsync(s => notification.RoleNum.Contains(s.RoleNum), cancellationToken: cancellationToken);
        await mediator.Send(new CreateUserSystemRolesCommand(new CreateUserSystemRolesDto()
        {

            UserId = notification.UserId,
            UserSystemRoles = roles.Select(s => new UserSystemRoleDto(s.SystemId, notification.UserId, s.Id, s.RoleNum)).ToList()
        }
           ),
            cancellationToken);
    }

    /// <summary>
    /// 用户变更事件
    /// </summary>
    /// <param name="notification"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public async Task Handle(ChangeUserDomainEvent notification, CancellationToken cancellationToken)
    {
        logger.LogInformation("Notification User Change {Notification}....", notification);
        var loginUserInfo = await userQueryService.BuildLoginUserInfo(notification.User);
        var oldUserInfo = await redisService.Database.StringGetWithExpiryAsync(loginUserInfo.Id.ToString());
        await redisService.Database.StringSetAsync(nameof(User) + ":" + loginUserInfo.Id.ToString(), JsonSerializeUtil.SerializeObject(loginUserInfo), oldUserInfo.Expiry ?? TimeSpan.FromSeconds(3600));
    }

    public async Task Handle(ChangePasswordDomainEvent notification, CancellationToken cancellationToken)
    {
        logger.LogInformation("Notification User Change Password {Notification}....", notification);
        //发送注销用户通知
        await mediator.Publish(new LogoutAccountNotification(notification.Id), cancellationToken);
    }


    public async Task Handle(UserChangeStatusDomainEvent notification, CancellationToken cancellationToken)
    {
        logger.LogInformation("Notification User Change Status {Notification}....", notification);
        if (notification.Status.Equals(UsetStatusEnum.Stop))
        {
            //发送注销用户通知
            await mediator.Publish(new LogoutAccountNotification(notification.Id), cancellationToken);
        }

    }
}